package Pakke;

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import static javax.swing.JOptionPane.*;

/**
 * FancyTimerGuiSettings.java
 *
 * Klassen setter opp settingsvindu bl.a to tabs, en for timerinnstillinger og en for alarminstillinger,
 * og plasserer komponenter av forskjellige slag inn i dem.
 *
 */

public class FancyTimerGuiSettings extends JFrame {

    private FancyTimerLogikk fancyTimerLogikk;
    private Box tim_storBoks;
    private Box tim_venstreBoks;
    private Box tim_hoyreBoks;
    private final String settingsTitle = "FancyTimer - Settings";
    private final String toolsIcon = "images/tools.gif";
    private final String soundIcon = "images/sound.gif";
    private final String newButtonString = "New";
    private final String deleteButtonString = "Delete";
    private final String editButtonString = "Edit";
    private Font settingsFont = new Font("Century Gothic", Font.BOLD, 12);
    private ListListener listListener = new ListListener();
    private JFrame parentFrame;



    /**
     * Konstruktør, FancyTimerGuiSettings. Setter opp JFrame, JTabbedPane og to JPanel som settes inn i som hver sin tab.
     * Panel1 settes opp vha metoden makeTimerPanel() og panel2 vha makeAlarmPanel().
     *
     * @param ftl Objekt av klassen FancyTimerLogikk
     * @param parentFrame JFrame
     */
    public FancyTimerGuiSettings(FancyTimerLogikk ftl, JFrame parentFrame){
        super();
        this.parentFrame = parentFrame;
        this.fancyTimerLogikk = ftl;
        //setLayout(new GridLayout());
        setTitle(settingsTitle);
        setLocationByPlatform(true);
        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        addWindowListener(new SettingsWindowListener());
        JTabbedPane tabbedPane = new JTabbedPane();
        ImageIcon iconTools = createImageIcon(toolsIcon);
        ImageIcon iconSound = createImageIcon(soundIcon);

        JComponent panel1 = makeTimerPanel();
        tabbedPane.addTab("General", iconTools, panel1, "Create and set your favorite Timers");

        JComponent panel2 = makeAlarmPanel();
        tabbedPane.addTab("Alarms Settings", iconSound, panel2, "Configure alarmtypes");
        add(tabbedPane);
    }

    /**
     * Vinduslytter for hovedvinduet. Aktiverer foreldrevinduet når dette vinduet lukkes.
     */
    private class SettingsWindowListener implements WindowListener {

        public void windowOpened(WindowEvent e) {
        }

        public void windowClosing(WindowEvent e) {
            dispose();
            parentFrame.setEnabled(true);
        }

        public void windowClosed(WindowEvent e) {
        }

        public void windowIconified(WindowEvent e) {
        }

        public void windowDeiconified(WindowEvent e) {
        }

        public void windowActivated(WindowEvent e) {
        }

        public void windowDeactivated(WindowEvent e) {
        }

    }

    /**
     * Når man trykker på notificationikonet skjer det her.
     * Metoden oppretter JPanel, setter opp bokser og paneler, legger disse inn i panelet.
     * @return En JPanel der bokser og paneler blir satt opp.
     */

    private JComponent makeTimerPanel(){
        JPanel jptp = new JPanel();
        jptp.add(setUpFramesTimerPanel());
        return jptp;
    }


    /**
     * Når man trykker på alarmknappen skjer dette.
     * Metoden oppretter JPanel, der legges det til et objekt av klassen FancyTimerGuiSettingsNotifications.
     *
     * @return JPanel med objekt av klassen FancyTimerGuiSettingsNotifications.
     */
    private JComponent makeAlarmPanel(){
        JPanel jpap = new JPanel();
        jpap.add(new FancyTimerGuiSettingsNotifications(fancyTimerLogikk)); //HUSK Å ENDRE TIL setUpFramesAlarmPanel
        return jpap;
    }


    /**
     *
     * Setter opp alle bokser; venstreBoks og hoyreBoks plasseres inne i tim_storBoks
     * @return completeBox
     */
    public Box setUpFramesTimerPanel() {
        tim_storBoks = Box.createHorizontalBox();
        tim_venstreBoks = FancyTimerStatic.createVerticalBox("Timers");
        tim_venstreBoks.add(new TimerListPanel());
        tim_venstreBoks.add(new ButtonPanel());
        tim_hoyreBoks = Box.createVerticalBox();
        tim_hoyreBoks.add(new InfoLabelPanel(-1));
        tim_storBoks.add(tim_venstreBoks);
        tim_storBoks.add(tim_hoyreBoks);
        //validate();
        return tim_storBoks;
    }


    /**
     * Privat klasse, ButtonPanel.
     * Dette er et knappepanel, her opprettes knappene "ny", "endre" og "slett".
     * Disse knappene plasseres inn i venstreBoks.
     *
     */
    private class ButtonPanel extends JPanel {
        public ButtonPanel() {  //Standard layouthåndterer FlowLayout
            ButtonListener buttonListener = new ButtonListener();

            JButton newButton = new JButton(newButtonString);
            newButton.setFont(settingsFont);
            newButton.addActionListener(buttonListener);
            add(newButton);

            JButton editButton = new JButton(editButtonString);
            editButton.setFont(settingsFont);
            editButton.addActionListener(buttonListener);
            add(editButton);

            JButton deleteButton = new JButton(deleteButtonString);
            deleteButton.setFont(settingsFont);
            deleteButton.addActionListener(buttonListener);
            add(deleteButton);
        }
    }

    /**
     * Privat klasse, InfoLabelPanel.
     * Infopanel: panelet som kommer når du trykker på en timer i JList.
     * Da kommer info om timeren opp.
     * Dette panelet skal inn i hoyreBoks.
     */
   private class InfoLabelPanel extends JPanel {

       private JCheckBox checkBox;
       private String[] data;
       private JTextField navn;
       private JTextField alt1;
       private JTextField alt2;
       private JTextField alt3;
       private JTextField alt4;
       private JTextField alt5;
       private JTextField alt6;

       /**
        * Konstruktør, InfoLabelPanel.
        * Tre paneler settes inn i et JPanel. Grunnen til at dette infopanelet
        * er delt inn i 3 paneler er for å få et bedre oppsett utseendemessig.
        * GridLayout brukes inni hvert panel, inkludert hovedpanelet.
        * @param valg Alle timere har en ID, dette er her valg du gjør i JList'en av timere.
        */
       public InfoLabelPanel(int valg) {
           setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
           setBorder(createBorder("Timer info"));
           setPreferredSize(new Dimension(280,275));

           JPanel panel1 = new JPanel();
           panel1.setLayout(new GridLayout(2,2));

           JPanel panel2 = new JPanel();
           panel2.setLayout(new GridLayout(4,2));

           JPanel panel3 = new JPanel();
           panel3.setLayout(new GridLayout(2,2));
           if (valg == -1) {
               data = new String[9];
               data[0] = "";
               data[1] = "";
               data[2] = "";
               data[3] = "";
               data[4] = "00:00:00";
               data[5] = "";
               data[6] = "00:00:00";
               data[7] = "";
               data[8] = "00:00:00";
           }
           else data = fancyTimerLogikk.getTimerInfo(valg);

           JLabel leadingText = new JLabel("Name", JLabel.LEFT);
           leadingText.setFont(settingsFont);
           panel1.add(leadingText);
           navn = new JTextField(data[0]);
           navn.setEditable(false);
           panel1.add(navn);

           leadingText = new JLabel("Notification", JLabel.LEFT);
           leadingText.setFont(settingsFont);
           String[] notificationStringList = fancyTimerLogikk.getNotificationList();
           int l = 0;
           for (String s: notificationStringList) {
                if (s.equals(data[1])) break;
                l++;
           }
           if (l >= notificationStringList.length) l = 0;
           JTextField notification = new JTextField(notificationStringList[l]);
           notification.setEditable(false);
           panel1.add(leadingText);
           panel1.add(notification);

           leadingText = new JLabel("Alternatives", JLabel.LEFT);
           leadingText.setFont(settingsFont);
           panel2.add(leadingText);
           alt1 = new JTextField(data[3]);
           alt2 = new JTextField(data[4]);
           alt3 = new JTextField(data[5]);
           alt4 = new JTextField(data[6]);
           alt5 = new JTextField(data[7]);
           alt6 = new JTextField(data[8]);
           panel2.add(new JLabel(""));
           alt1.setEditable(false);
           alt2.setEditable(false);
           alt3.setEditable(false);
           alt4.setEditable(false);
           alt5.setEditable(false);
           alt6.setEditable(false);
           panel2.add(alt1);
           panel2.add(alt2);

           panel2.add(alt3);
           panel2.add(alt4);

           panel2.add(alt5);
           panel2.add(alt6);
           checkBox = new JCheckBox("Favourite");
           if (data[2].equals("Favoritt")) checkBox.setSelected(true);
           checkBox.setFont(settingsFont);
           checkBox.setEnabled(false);
           panel3.add(checkBox);
           panel3.add(new JLabel(""));
           JButton jb = new JButton("a");
           jb.setVisible(false);
           panel3.add(jb);
           add(panel1);
           add(Box.createGlue());
           add(panel2);
           add(Box.createGlue());
           add(panel3);
       }

   }

   /**
    * Panelet som kommer når du trykker new/endre.
    */
   private class EditTimerPanel extends JPanel {

       private JCheckBox checkBox;
       private String[] data;
       private JTextField navn;
       private JComboBox notificationList;
       private JTextField alt1;
       private JTextField alt2;
       private JTextField alt3;
       private JTextField alt4;
       private JTextField alt5;
       private JTextField alt6;

       /**
        *
        * @return Innholdet i en tekstboks
        */
        public String getAlt1() {
            return alt1.getText().trim();
        }
        /**
        *
        * @return Innholdet i en tekstboks
        */
        public String getAlt2() {
            return alt2.getText().trim();
        }
        /**
        *
        * @return Innholdet i en tekstboks
        */
        public String getAlt3() {
            return alt3.getText().trim();
        }
        /**
        *
        * @return Innholdet i en tekstboks
        */
        public String getAlt4() {
            return alt4.getText().trim();
        }
        /**
        *
        * @return Innholdet i en tekstboks
        */
        public String getAlt5() {
            return alt5.getText().trim();
        }
        /**
        *
        * @return Innholdet i en tekstboks
        */
        public String getAlt6() {
            return alt6.getText().trim();
        }
        /**
        *
        * @return Innholdet i en tekstboks
        */
        public Boolean getCheckBox() {
            return checkBox.isSelected();
        }
        /**
        *
        * @return Innholdet i en tekstboks
        */
        public String getData() {
            return data[0];
        }
        /**
        *
        * @return Innholdet i en tekstboks
        */
        @Override
        public String getName() {
            return navn.getText().trim();
        }
        /**
        *
        * @return Den valgte indeksen i en JComboBox
        */
        public int getNotificationList() {
            return notificationList.getSelectedIndex();
        }

        /**
         * Konstruktør. Her opprettes 3 paneler, som settes inn i et stort panel.
         * Hvert panel bruker GridLayout. Disse tre panelene inneholder tekstbokser
         * der brukeren kan endre på forskjellig data om en timer.
         * @param valg Alle timere har en ID, dette er her valg du gjør i JList'en av timere.
         */
        public EditTimerPanel(int valg) {
           setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
           setBorder(createBorder("Edit"));
           setPreferredSize(new Dimension(280,275));

           JPanel panel1 = new JPanel();
           panel1.setLayout(new GridLayout(2,2));

           JPanel panel2 = new JPanel();
           panel2.setLayout(new GridLayout(4,2));

           JPanel panel3 = new JPanel();
           panel3.setLayout(new GridLayout(2,2));
           if (valg == -1) {
               data = new String[9];
               data[0] = "Timer name";
               data[1] = "";
               data[2] = "Favoritt";
               data[3] = "Alt 1";
               data[4] = "HH:MM:SS";
               data[5] = "Alt 2";
               data[6] = "HH:MM:SS";
               data[7] = "Alt 3";
               data[8] = "HH:MM:SS";
           }
           else data = fancyTimerLogikk.getTimerInfo(valg);

           JLabel leadingText = new JLabel("Name", JLabel.LEFT);
           leadingText.setFont(settingsFont);
           panel1.add(leadingText);
           navn = new JTextField(data[0]);
           panel1.add(navn);

           leadingText = new JLabel("Notification", JLabel.LEFT);
           leadingText.setFont(settingsFont);
           String[] notificationStringList = fancyTimerLogikk.getNotificationList();
           int l = 0;
           for (String s: notificationStringList) {
                if (s.equals(data[1])) break;
                l++;
           }
           if (l >= notificationStringList.length) l = 0;
           notificationList = new JComboBox(notificationStringList);
           notificationList.setSelectedIndex(l);

           panel1.add(leadingText);
           panel1.add(notificationList);

           leadingText = new JLabel("Alternatives", JLabel.LEFT);
           leadingText.setFont(settingsFont);
           panel2.add(leadingText);
           alt1 = new JTextField(data[3]);
           alt2 = new JTextField(data[4]);
           alt3 = new JTextField(data[5]);
           alt4 = new JTextField(data[6]);
           alt5 = new JTextField(data[7]);
           alt6 = new JTextField(data[8]);
           panel2.add(new JLabel(""));
           panel2.add(alt1);
           panel2.add(alt2);
           
           panel2.add(alt3);
           panel2.add(alt4);

           panel2.add(alt5);
           panel2.add(alt6);
           checkBox = new JCheckBox("Favourite");
           if (data[2].equals("Favoritt")) checkBox.setSelected(true);
           checkBox.setFont(settingsFont);
           JButton finishButton = new JButton("Save");
           finishButton.setFont(settingsFont);
           finishButton.addActionListener(new ButtonListener()); //kjhgkhf
           panel3.add(checkBox);
           panel3.add(new JLabel(""));
           panel3.add(finishButton);
           add(panel1);
           add(Box.createGlue());
           add(panel2);
           add(Box.createGlue());
           add(panel3);
       }
   }


   /**
    * Panelet som viser en JList med timere
    */
   private class TimerListPanel extends JPanel {
       /**
        * Konstruktør. En JList med timere settes inn i et JPanel.
        */
       public TimerListPanel() {
           setLayout(new GridLayout(1,1));
           JList timerList = createJListWithTimers();
           JScrollPane timerListScroll = new JScrollPane(timerList);
           timerList.setFont(settingsFont);
           add(timerListScroll);
       }
       /**
        * Metoden oppretter og returnerer en JList.
        * En String-tabell med timere hentes fra FancyTimerLogikk og plasseres inn i JList'en.
        * @return En JList med timere.
        */
       private JList createJListWithTimers() {
            JList timerJList = new JList(fancyTimerLogikk.getTimerList());
            timerJList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
           // timerJList.setFixedCellWidth(200);
            timerJList.setSize(500, 600);
            listListener = new ListListener();
            timerJList.addListSelectionListener(listListener);
            return timerJList;
    }
   }

    /**
     *
     * 
     * Metoden oppdaterer høyreboksen slik at det som vises der avhenger av
     * hva du har trykket på i JList (timer)
     *
     * @param valg Alle timere har en ID, dette er her valg du gjør i JList'en av timere.
     */
    private void updateRightBox(int valg) {
        tim_storBoks.remove(tim_hoyreBoks);
        tim_hoyreBoks.removeAll();
        tim_hoyreBoks = Box.createVerticalBox();
        tim_hoyreBoks.add(new InfoLabelPanel(valg));
        tim_storBoks.add(tim_hoyreBoks);
        validate();
    }

    /**
     * Metoden oppdaterer venstreboksen
     */
    private void updateLeftBox() {
        tim_storBoks.remove(tim_venstreBoks);
        tim_venstreBoks.removeAll();
        tim_venstreBoks = FancyTimerStatic.createVerticalBox("Timers");
        tim_venstreBoks.add(new TimerListPanel());
        tim_venstreBoks.add(new ButtonPanel());
        tim_storBoks.add(tim_venstreBoks);
        updateRightBox(-1);
        validate();
    
    }

    /**
     * Metoden oppdaterer høyreboksen dersom brukeren har trykket "edit",
     * altså hvis man vil endre på data til en timer.
     *
     * @param valg Alle timere har en ID, dette er her valg du gjør i JList'en av timere.
     */
    private void updateRightBoxIfEdit(int valg) {
        tim_storBoks.remove(tim_hoyreBoks);
        tim_hoyreBoks.removeAll();
        tim_hoyreBoks = Box.createHorizontalBox();
        tim_hoyreBoks.add(new EditTimerPanel(valg));
        tim_storBoks.add(tim_hoyreBoks);
        validate();
    }


    /**
     * Listelytter, lytter til klikk i JList med timere
     */
    private class ListListener implements ListSelectionListener {
        private int selectedTimer;
        public ListListener() {
            super();
        }

        /**
         * Oppdaterer høyreboks ettersom valg man gjør i JList over timere.
         * @param e
         */
        public void valueChanged(ListSelectionEvent e) {
            JList jlt = (JList) e.getSource();
            selectedTimer = jlt.getSelectedIndex();
            updateRightBox(jlt.getSelectedIndex());
        }

        /**
         *
         * @return Den valgte timeren i JList over timere.
         */
        public int getSelectedTimer() {
            return selectedTimer;
        }
    }

    /**
     * Knappelytter, lutter til klikk i knappene "new", "edit" og "delete"
     * og utfører operasjoner deretter.
     */
    private class ButtonListener implements ActionListener {
        public ButtonListener() {
            super();
        }
        /*
         *
         * Her utføres det operasjoner ettersom hvilken knapp man har trykket på,
         * i tillegg til at høyreboksen oppdateres.
         */
        public void actionPerformed(ActionEvent event) {
            if(event.getActionCommand().equals(newButtonString)) {
                updateRightBoxIfEdit(-1);
            }
            if (event.getActionCommand().equals(editButtonString)) {
                updateRightBoxIfEdit(listListener.getSelectedTimer());

            }
            if (event.getActionCommand().equals(deleteButtonString)) {
                String[] buttons = {"Delete", "Cancel"};
                int i = JOptionPane.showOptionDialog(null, "Are you sure you want to delete this timer?", "Delete timer", JOptionPane.OK_CANCEL_OPTION,
                        JOptionPane.QUESTION_MESSAGE, null,buttons, buttons[1]);
                if (i == 0) {
                    deleteTimer(listListener.getSelectedTimer());
                }
            }

            if (event.getActionCommand().equals("Save")) {
                updateTimer(event.getSource());

            }
        }




    }   


    /**
     * Returns an ImageIcon, or null if the path was invalid.
     */
    private static ImageIcon createImageIcon(String path) {
        java.net.URL imgURL = FancyTimerGuiSettings.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }

    /**
     * Metoden oppretter og returnerer en bord.
     * @param title Dette er det som skal stå øverst i borden.
     * @return En bord
     */
    private static Border createBorder(String title) {
        TitledBorder bb = new TitledBorder(title);
        EmptyBorder eb = new EmptyBorder(5, 5, 5, 5);
        CompoundBorder cb = new CompoundBorder(bb, eb);
        CompoundBorder cb2 = new CompoundBorder(eb, cb);
        return cb2;
    }

    /**
     * Metoden sletter et helt timer-objekt.
     *
     * @param i ID'en til en timer.
     */
    private void deleteTimer(int i) {
            fancyTimerLogikk.deleteTimerData(i);
            fancyTimerLogikk.saveAllData();
            updateLeftBox();
    }

    /**
     * Oppdaterer et timer-objekt, f.eks når du har gjort endringer på en timer og vil lagre endringene.
     *
     */
    private void updateTimer(Object source) {
            boolean bad = false;
            boolean update = true;
            boolean dupe = false;
            JButton jsource = (JButton)source;
            JPanel jpanel = (JPanel)jsource.getParent();
            EditTimerPanel etp = (EditTimerPanel)jpanel.getParent();
            if (etp.getData().equals("Timer name")) update = false;
            if (etp.getName().equals("") || etp.getAlt1().equals("") || etp.getAlt3().equals("") || etp.getAlt5().equals("")) bad = true;
            int intAlt1 = stringToSec(etp.getAlt2());
            int intAlt3 = stringToSec(etp.getAlt4());
            int intAlt5 = stringToSec(etp.getAlt6());
            if ((intAlt1 < 0) || (intAlt3 < 0) || (intAlt5 < 0)) bad = true;
            if (bad) { showMessageDialog(null, "Alert", "Error", JOptionPane.ERROR_MESSAGE);}
            //if (!update) {
                String[] str = fancyTimerLogikk.getTimerList();
                for (String s: str) {
                    if (s.trim().equals(etp.getName())) {
                        if (s.trim().equals(etp.getData())) break;
                        showMessageDialog(null, "A timer with this name already exists.", "Alert", JOptionPane.ERROR_MESSAGE);
                        dupe = true;
                    }
            //    }
            }
            if (!bad && !dupe) {
                ArrayList<LTimerAlternative> lta = new ArrayList<LTimerAlternative>();
                lta.add(new LTimerAlternative(etp.getAlt1(), intAlt1*1000)); 
                lta.add(new LTimerAlternative(etp.getAlt3(), intAlt3*1000)); 
                lta.add(new LTimerAlternative(etp.getAlt5(), intAlt5*1000)); 
                LTimerData ltd = new LTimerData(etp.getName(), fancyTimerLogikk.getNotificationList()[etp.getNotificationList()], lta, 0 , etp.getCheckBox());
                if(update) {
                    int t = 0;
                    str = fancyTimerLogikk.getTimerList();
                    for (String s: str) {
                        if (s.equals(etp.getData())) {fancyTimerLogikk.deleteTimerData(t); break;}
                        t++;
                    }
                }
                fancyTimerLogikk.addTimerData(ltd);
                updateLeftBox();
                fancyTimerLogikk.saveAllData();
            }

    }

    /**
     * Metoden gjør om en string til int. Her brukes det når man skriver inn en
     * alternativtid, som til å begynne med er en string.
     * @param input En string
     * @return En int
     */
    public static int stringToSec(String input){
        try{
            StringTokenizer st = new StringTokenizer(input, ":");
            int timer = Integer.parseInt(st.nextToken());
            //System.out.println(timer);
            int minutter = Integer.parseInt(st.nextToken());
            //System.out.println(minutter);
            int sekunder = Integer.parseInt(st.nextToken());
            //System.out.println(sekunder);
            sekunder += timer * 60 * 60;
            sekunder += minutter * 60;
            //System.out.println(sekunder);
            return sekunder;
        }catch(Exception e){
            //System.out.println("baaah, crap fucked up");
            return -1;
        }
    }
}